﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace Solidi
{
	public abstract class GenericDependencyResolver : DependencyResolverDecorator 
    {
        private Type _builderType;

        public GenericDependencyResolver(IDependencyResolver resolver, Type builderType)
			: base(resolver)
		{
            if (builderType == null)
            {
                throw new ArgumentNullException("builderType");
            }

            _builderType = builderType;
		}

		protected abstract bool IsTargetGenericType(Type genericTypeDefinition);

		public override object Resolve(IDependencyContext container, IDependencyKey key)
		{
            if (key == null)
            {
                throw new ArgumentNullException("key");
            }

			object instance = base.Resolve(container, key);

			if (instance == null)
			{
                Type type = key.Type;

                if (type.IsGenericType)
                {
					if (IsTargetGenericType(type.GetGenericTypeDefinition()))
					{
                        Type[] typeArguments = type.GetGenericArguments();

                        if (typeArguments.Length == 1)
                        {
                            Type returnType = typeArguments[0];

                            GenericDependencyFactory builder = (GenericDependencyFactory)Activator.CreateInstance(_builderType.MakeGenericType(returnType));

                            instance = builder.Create(container, new DependencyKey(key, returnType));
                        }
                    }
                }
            }

            return instance;
        }
    }
}
